package lifecycle

import (
	"context"
	"fmt"
	"sync"
	"time"
)

// RemoteMessage 表示远程消息
type RemoteMessage struct {
	// SenderID 是发送者ID
	SenderID string
	// ReceiverID 是接收者ID
	ReceiverID string
	// MessageType 是消息类型
	MessageType string
	// Payload 是消息负载
	Payload []byte
	// Timestamp 是消息时间戳
	Timestamp time.Time
	// Headers 是消息头
	Headers map[string]string
	// ID 是消息ID
	ID string
}

// RemoteActorRef 表示远程Actor引用
type RemoteActorRef struct {
	// ID 是Actor ID
	ID string
	// Address 是Actor地址
	Address string
	// NodeID 是节点ID
	NodeID string
}

// RemoteActorRegistry 表示远程Actor注册表
type RemoteActorRegistry struct {
	// actors 是Actor映射表
	actors map[string]*RemoteActorRef
	// mu 是互斥锁
	mu sync.RWMutex
}

// NewRemoteActorRegistry 创建一个新的远程Actor注册表
func NewRemoteActorRegistry() *RemoteActorRegistry {
	return &RemoteActorRegistry{
		actors: make(map[string]*RemoteActorRef),
	}
}

// Register 注册远程Actor
func (r *RemoteActorRegistry) Register(ref *RemoteActorRef) {
	r.mu.Lock()
	defer r.mu.Unlock()
	r.actors[ref.ID] = ref
}

// Unregister 注销远程Actor
func (r *RemoteActorRegistry) Unregister(id string) {
	r.mu.Lock()
	defer r.mu.Unlock()
	delete(r.actors, id)
}

// Lookup 查找远程Actor
func (r *RemoteActorRegistry) Lookup(id string) (*RemoteActorRef, bool) {
	r.mu.RLock()
	defer r.mu.RUnlock()
	ref, ok := r.actors[id]
	return ref, ok
}

// List 列出所有远程Actor
func (r *RemoteActorRegistry) List() []*RemoteActorRef {
	r.mu.RLock()
	defer r.mu.RUnlock()
	refs := make([]*RemoteActorRef, 0, len(r.actors))
	for _, ref := range r.actors {
		refs = append(refs, ref)
	}
	return refs
}

// RemoteTransport 表示远程传输接口
type RemoteTransport interface {
	// Send 发送消息
	Send(ctx context.Context, message *RemoteMessage) error
	// Receive 接收消息
	Receive(ctx context.Context) (*RemoteMessage, error)
	// Start 启动传输
	Start(ctx context.Context) error
	// Stop 停止传输
	Stop(ctx context.Context) error
}

// RemoteActorSystem 表示远程Actor系统
type RemoteActorSystem struct {
	// NodeID 是节点ID
	NodeID string
	// Address 是节点地址
	Address string
	// Registry 是Actor注册表
	Registry *RemoteActorRegistry
	// Transport 是远程传输
	Transport RemoteTransport
	// messageHandlers 是消息处理器映射表
	messageHandlers map[string]func(*RemoteMessage) error
	// mu 是互斥锁
	mu sync.RWMutex
	// running 表示系统是否运行中
	running bool
	// ctx 是上下文
	ctx context.Context
	// cancel 是取消函数
	cancel context.CancelFunc
}

// NewRemoteActorSystem 创建一个新的远程Actor系统
func NewRemoteActorSystem(nodeID string, address string, transport RemoteTransport) *RemoteActorSystem {
	ctx, cancel := context.WithCancel(context.Background())
	return &RemoteActorSystem{
		NodeID:          nodeID,
		Address:         address,
		Registry:        NewRemoteActorRegistry(),
		Transport:       transport,
		messageHandlers: make(map[string]func(*RemoteMessage) error),
		running:         false,
		ctx:             ctx,
		cancel:          cancel,
	}
}

// Start 启动远程Actor系统
func (s *RemoteActorSystem) Start() error {
	s.mu.Lock()
	defer s.mu.Unlock()

	if s.running {
		return fmt.Errorf("remote actor system is already running")
	}

	// 启动传输
	if err := s.Transport.Start(s.ctx); err != nil {
		return fmt.Errorf("failed to start transport: %w", err)
	}

	// 启动消息接收循环
	go s.receiveLoop()

	s.running = true
	return nil
}

// Stop 停止远程Actor系统
func (s *RemoteActorSystem) Stop() error {
	s.mu.Lock()
	defer s.mu.Unlock()

	if !s.running {
		return fmt.Errorf("remote actor system is not running")
	}

	// 取消上下文
	s.cancel()

	// 停止传输
	if err := s.Transport.Stop(context.Background()); err != nil {
		return fmt.Errorf("failed to stop transport: %w", err)
	}

	s.running = false
	return nil
}

// RegisterActor 注册Actor
func (s *RemoteActorSystem) RegisterActor(id string) *RemoteActorRef {
	ref := &RemoteActorRef{
		ID:      id,
		Address: s.Address,
		NodeID:  s.NodeID,
	}
	s.Registry.Register(ref)
	return ref
}

// UnregisterActor 注销Actor
func (s *RemoteActorSystem) UnregisterActor(id string) {
	s.Registry.Unregister(id)
}

// RegisterMessageHandler 注册消息处理器
func (s *RemoteActorSystem) RegisterMessageHandler(messageType string, handler func(*RemoteMessage) error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.messageHandlers[messageType] = handler
}

// Send 发送消息
func (s *RemoteActorSystem) Send(ctx context.Context, message *RemoteMessage) error {
	if !s.running {
		return fmt.Errorf("remote actor system is not running")
	}

	return s.Transport.Send(ctx, message)
}

// receiveLoop 接收循环
func (s *RemoteActorSystem) receiveLoop() {
	for {
		select {
		case <-s.ctx.Done():
			return
		default:
			message, err := s.Transport.Receive(s.ctx)
			if err != nil {
				// 处理错误，这里简单地记录错误
				fmt.Printf("Failed to receive message: %v\n", err)
				continue
			}

			// 处理消息
			s.handleMessage(message)
		}
	}
}

// handleMessage 处理消息
func (s *RemoteActorSystem) handleMessage(message *RemoteMessage) {
	s.mu.RLock()
	handler, ok := s.messageHandlers[message.MessageType]
	s.mu.RUnlock()

	if !ok {
		// 未找到处理器，这里简单地记录错误
		fmt.Printf("No handler for message type: %s\n", message.MessageType)
		return
	}

	// 调用处理器
	if err := handler(message); err != nil {
		// 处理错误，这里简单地记录错误
		fmt.Printf("Failed to handle message: %v\n", err)
	}
}

// RemoteLifecycleAwareActor 表示具有远程通信能力的生命周期感知Actor
type RemoteLifecycleAwareActor struct {
	// LifecycleAwareActor 是基础Actor
	LifecycleAwareActor
	// RemoteSystem 是远程Actor系统
	RemoteSystem *RemoteActorSystem
	// RemoteRef 是远程Actor引用
	RemoteRef *RemoteActorRef
}

// NewRemoteLifecycleAwareActor 创建一个新的远程生命周期感知Actor
func NewRemoteLifecycleAwareActor(id string, remoteSystem *RemoteActorSystem) *RemoteLifecycleAwareActor {
	actor := &RemoteLifecycleAwareActor{
		RemoteSystem: remoteSystem,
	}
	actor.Initialize(id)
	actor.RemoteRef = remoteSystem.RegisterActor(id)
	return actor
}

// OnStop 停止Actor
func (a *RemoteLifecycleAwareActor) OnStop() error {
	// 调用基类方法
	if err := a.LifecycleAwareActor.OnStop(); err != nil {
		return err
	}

	// 注销远程Actor
	a.RemoteSystem.UnregisterActor(a.Metrics.ID)
	return nil
}

// SendRemote 发送远程消息
func (a *RemoteLifecycleAwareActor) SendRemote(ctx context.Context, receiverID string, messageType string, payload []byte, headers map[string]string) error {
	message := &RemoteMessage{
		SenderID:    a.Metrics.ID,
		ReceiverID:  receiverID,
		MessageType: messageType,
		Payload:     payload,
		Timestamp:   time.Now(),
		Headers:     headers,
		ID:          fmt.Sprintf("%s-%s-%d", a.Metrics.ID, receiverID, time.Now().UnixNano()),
	}

	return a.RemoteSystem.Send(ctx, message)
}
